/*
 * Copyright (C) 2012 Tomas Shestakov. <http://code.google.com/p/jmmo/>
 */

package jmmo.engine.property

import org.scalatest.WordSpec
import org.scalatest.matchers.ShouldMatchers
import org.scalatest.mock.MockitoSugar
import org.mockito.Mockito._

/**
 * @author Tomas Shestakov
 */
class BoundPropertySpec(boundProp: BoundProperty[Int]) extends WordSpec with ShouldMatchers with MockitoSugar {

  def this() = this(BoundProperty[Int]())

  val s = Property("abc")
  val k = Property(3)
  boundProp.binding = Binding[Int, String, Int]((s, k) => s.length * k, s, k)

  override val nestedSuites = List(new PropertySpec(boundProp))

  val mockListenerInt = mock[ChangeListeners.Listener]
  when(mockListenerInt.isDefinedAt(org.mockito.Matchers.any())).thenReturn(true)

  "A BoundProperty" when afterWord("binding var") {

    "sets to Binding with predicate and Properites on which this will depends (means property is bound)" should {

      "be readable" in {
        //boundProp.binding = Binding[Int, String, Int]((s, k) => s.length * k, s, k)
        boundProp.isReadable should be(true)
      }

      "apply method returns predicate value" in {
        boundProp() should be(9)
      }

      "changes parent property value produce ChangePropertyEvent of depended property" in {
        boundProp.addChangeListener(mockListenerInt)
        k() = 2
        verify(mockListenerInt).apply(ChangePropertyEvent(boundProp, 9, 6))
        s() = "12345"
        verify(mockListenerInt).apply(ChangePropertyEvent(boundProp, 6, 10))
//        verifyNoMoreInteractions(mockListenerInt)
      }
    }

    "sets to null (means property is not bound)" should {

      "be not readable" in {
        boundProp.binding = null

        boundProp.isReadable should be(false)
      }

      "apply method produce UnsupportedOperationException" in {
        evaluating {
          boundProp()
        } should produce[UnsupportedOperationException]
      }

      "changes former parent property value not produce any event of depended property" in {
        k() = 5
        s() = "abcd"
        verify(mockListenerInt, never()).apply(ChangePropertyEvent(boundProp, 10, 5))
//        verifyNoMoreInteractions(mockListenerInt)
      }
    }
  }
}
